import { GameConfig } from "../configs/GameConfig";
import { ILevelElement } from "../configs/Level";
import { ISubLevelElement as ICheckpointElement } from "../configs/SubLevel";

export class Level {
    cfg: ILevelElement;
    endPointTrigger: Trigger;

    private onSelfEnter: (cfg: ILevelElement) => void;
    private caller: any;

    constructor(levelCfg: ILevelElement, onSelfEnter: (cfg: ILevelElement) => void, caller: any) {
    }

    private onSelfCharacterEnterCheckPoint = this._onSelfCharacterEnterCheckPoint.bind(this);
    private _onSelfCharacterEnterCheckPoint(other: GameObject) {
        if (!(other instanceof Character)) return;
        let character = <Character>other;
        if (character != Player.localPlayer.character) return;

        this.onSelfEnter.call(this.caller, this.cfg);
    }
}

export class CheckPoint {
    // 当前检查点配置表
    cfg: ICheckpointElement;
    // 下一关检查点配置表
    nextCheckpointCfg: ICheckpointElement | undefined;
    // 下一关检查点
    nextCheckpointTrigger: Trigger | undefined;

    // 进入下一个检查点回调
    private onSelfEnterNextCheckPoint: (cfg: ICheckpointElement) => void;
    private caller: any;

    // 设置当前玩家所处检查点
    constructor(cfg: ICheckpointElement, onSelfEnterNextCheckPoint: (cfg: ICheckpointElement) => void, caller: any) {
        this.resetCfg(cfg.ID);
        this.onSelfEnterNextCheckPoint = onSelfEnterNextCheckPoint;
        this.caller = caller;
    }

    // 获取当前检查点的起始位置
    getCurrentCheckpointStartPosition(): Vector {
        let trigger = GameObject.findGameObjectById(this.cfg.CheckpointStartPositionTriggerGUID);
        return trigger.worldTransform.position
    }

    // 获取当前检查点的触发器底部位置
    getCurrentCheckpointStartTriggerBottomPosition(): Vector {
        let trigger = GameObject.findGameObjectById(this.cfg.CheckpointStartPositionTriggerGUID);
        let position = trigger.worldTransform.position
        position.z -= trigger.getBoundingBoxExtent().z / 2
        return position
    }

    // 获取下一个检查点的起始位置
    getNextCheckpointStartPosition(): Vector {
        if(!this.nextCheckpointCfg){
            console.error(`逻辑错误!, 当前cfg没有下一个检查点信息${this.cfg.ID}`);
            return this.getCurrentCheckpointStartPosition()
        }
        let trigger = GameObject.findGameObjectById(this.nextCheckpointCfg.CheckpointStartPositionTriggerGUID);
        return trigger.worldTransform.position
    }

    // 获取当前检查点的触发器底部位置
    getNextCheckpointStartTriggerBottomPosition(): Vector {
        if(!this.nextCheckpointCfg){
            console.error(`逻辑错误!, 当前cfg没有下一个检查点信息${this.cfg.ID}`);
            return this.getCurrentCheckpointStartPosition()
        }
        let trigger = GameObject.findGameObjectById(this.nextCheckpointCfg.CheckpointStartPositionTriggerGUID);
        let position = trigger.worldTransform.position
        position.z -= trigger.getBoundingBoxExtent().z / 2
        return position
    }


    // 重置检查点
    resetCfg(cfgID: number) {
        // 清除上一个绑定的回调
        if (this.nextCheckpointTrigger) {
            this.nextCheckpointTrigger.onEnter.remove(this.onSelfCharacterEnterNextCheckpoint);
        }

        this.cfg = GameConfig.Checkpoint.getElement(cfgID);

        if (!this.isKindLastCheckpoint()) {
            this.nextCheckpointCfg = GameConfig.Checkpoint.getElement(this.cfg.Next)
            this.nextCheckpointTrigger = <Trigger>GameObject.findGameObjectById(this.nextCheckpointCfg.CheckpointStartPositionTriggerGUID);
            this.nextCheckpointTrigger.onEnter.add(this.onSelfCharacterEnterNextCheckpoint);
        } else {
            this.nextCheckpointCfg = undefined
            this.nextCheckpointTrigger = undefined
        }
    }
    
    // 是否是最后一个检查点
    isKindLastCheckpoint(): boolean {
        return this.cfg.Next == 0;
    }

    // 当前检查点是否为传送检查点
    isTransferCheckpoint(): boolean {
        return this.cfg.IsTransfer
    }

    // 下一个检查点是否为传送检查点
    nextCheckpointIsTransferCheckpoint(): boolean {
        return this.nextCheckpointCfg && this.nextCheckpointCfg.IsTransfer
    }

    private onSelfCharacterEnterNextCheckpoint = this._onSelfCharacterEnterNextCheckpoint.bind(this);
    private _onSelfCharacterEnterNextCheckpoint(other: GameObject) {
        if (!(other instanceof Character)) return;
        if (<Character> other != Player.localPlayer.character) return;

        this.onSelfEnterNextCheckPoint.call(this.caller, this.cfg);
    }
}